package com.car.loan.project.xr.service;

import com.car.loan.common.SnowflakeIdWorker;
import com.car.loan.common.exception.loan.LoanParameterException;
import com.car.loan.common.utils.SecurityUtils;
import com.car.loan.common.utils.qiniu.QiniuUtil;
import com.car.loan.framework.aspectj.lang.enums.BusinessStatus;
import com.car.loan.framework.web.domain.AjaxResult;
import com.car.loan.project.cd.mapper.CdCreditMapper;
import com.car.loan.project.cm.domain.CmBank;
import com.car.loan.project.system.service.ISysSequenceService;
import com.car.loan.project.ve.mapper.VeVehicleAlbumMapper;
import com.car.loan.project.ve.mapper.VeVehicleEvaluationMapper;
import com.car.loan.project.xr.domain.Customer;
import com.car.loan.project.xr.domain.Loan;
import com.car.loan.project.xr.domain.LoanCar;
import com.car.loan.project.xr.domain.LoanDetail;
import com.car.loan.project.xr.domain.LoanExt;
import com.car.loan.project.xr.domain.LoanStatus;
import com.car.loan.project.xr.mapper.CustomerDetailMapper;
import com.car.loan.project.xr.mapper.CustomerGuarantorMapper;
import com.car.loan.project.xr.mapper.CustomerMapper;
import com.car.loan.project.xr.mapper.CustomerSpouseMapper;
import com.car.loan.project.xr.mapper.LoanAlbumMapper;
import com.car.loan.project.xr.mapper.LoanCarMapper;
import com.car.loan.project.xr.mapper.LoanContactMapper;
import com.car.loan.project.xr.mapper.LoanDetailMapper;
import com.car.loan.project.xr.mapper.LoanExtMapper;
import com.car.loan.project.xr.mapper.LoanInsuranceMapper;
import com.car.loan.project.xr.mapper.LoanMapper;
import com.car.loan.project.xr.mapper.LoanStatusMapper;
import com.car.loan.project.xr.util.RedisDataUtil;
import com.car.loan.project.xr.util.bo.business.SettlementInfoBo;
import com.car.loan.project.xr.util.enums.LoanStatusEnum;
import com.car.loan.project.xr.util.enums.SettlementInfoStatus;
import com.car.loan.project.xr.util.repayment.RepaymentFormulaInterface;
import com.car.loan.project.xr.util.repayment.RepaymentPlanParam;
import com.car.loan.project.xr.util.vo.SettlementInfoVo;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author huangding
 * @date 2020/2/16 14:34
 */
@Service
public class SettlementService {

    @Autowired
    private LoanMapper loanMapper;


    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private LoanCarMapper loanCarMapper;

    @Autowired
    private LoanExtMapper loanExtMapper;

    @Autowired
    private LoanDetailMapper loanDetailMapper;

    @Autowired
    private LoanStatusMapper loanStatusMapper;

    @Autowired
    private RedisDataUtil redisDataUtil;


    public SettlementInfoVo getInfo(Long loanId) {
        SettlementInfoVo settlementInfoVo = new SettlementInfoVo();

        Optional<Loan> optionalLoan
            = Optional.ofNullable(loanMapper.selectById(loanId));
        Loan loan = optionalLoan.orElseThrow(() -> new LoanParameterException("无该业务数据"));
        //获取数据源
        Optional<LoanCar> optionalLoanCar = loanCarMapper.selectByLoanId(loanId);
        LoanCar loanCar = optionalLoanCar
            .orElseThrow(() -> new LoanParameterException("业务数据车辆信息异常"));
        Optional<LoanExt> optionalLoanExt = loanExtMapper.selectByLoanId(loanId);
        LoanExt loanExt = optionalLoanExt
            .orElseThrow(() -> new LoanParameterException("业务数据扩展信息异常"));
        Optional<LoanDetail> optionalLoanDetail = loanDetailMapper.selectByLoanId(loanId);
        LoanDetail loanDetail = optionalLoanDetail
            .orElseThrow(() -> new LoanParameterException("业务数据详情信息异常"));

        Optional<LoanStatus> optionalLoanStatus = loanStatusMapper.selectByLoanId(loanId);
        LoanStatus loanStatus = optionalLoanStatus
            .orElseThrow(() -> new LoanParameterException("业务状态数据异常请联系管理员"));

        Optional<Customer> optionalCustomer = Optional
            .ofNullable(customerMapper.selectById(loan.getCustomerId()));
        Customer customer = optionalCustomer
            .orElseThrow(() -> new LoanParameterException("该业务客户数据异常，请联系管理员"));

        CmBank cmBank = redisDataUtil.getRedisBankMap().get(loan.getBankId().toString());

        settlementInfoVo.setLoanId(loan.getId().toString());
        settlementInfoVo.setBusinessNo(loan.getBusinessNo());
        settlementInfoVo.setFileNo(loanDetail.getFileNo());
        settlementInfoVo.setDeptName(redisDataUtil.getDeptName(loan.getDeptId()));
        settlementInfoVo.setAdminName(redisDataUtil.getAdminName(loan.getAdminId()));
        settlementInfoVo.setDealerName(redisDataUtil.getDealerName(loan.getDealerId()));
        settlementInfoVo.setBankName(cmBank.getAlias());

        settlementInfoVo.setName(customer.getName());
        settlementInfoVo.setIdType(customer.getIdType());
        settlementInfoVo.setIdCardNo(customer.getIdCardNo());

        settlementInfoVo.setInstallmentAmount(loanExt.getInstallmentAmount());
        settlementInfoVo.setTerm(loanExt.getTerm());
        settlementInfoVo.setRate(loanExt.getRate());
        settlementInfoVo.setFinancingAmount(loanExt.getFinancingAmount());
        settlementInfoVo.setLendDate(loanDetail.getLendDate());
        settlementInfoVo.setRepayCardNo(loanDetail.getRepayCardNo());
        settlementInfoVo.setDeductionCardNo(loanDetail.getDeductionCardNo());
        settlementInfoVo.setFirstRepayDate(loanDetail.getFirstRepayDate());

        //车辆信息
        settlementInfoVo.setBrand(loanCar.getBrand());
        settlementInfoVo.setCarType(loanCar.getCarType());
        settlementInfoVo.setCarNature(loanCar.getCarNature());
        settlementInfoVo.setBankCarType(loanCar.getBankCarType());
        settlementInfoVo.setFrameNo(loanCar.getFrameNo());
        settlementInfoVo.setEngineNo(loanCar.getEngineNo());
        settlementInfoVo.setInvoiceUnit(loanCar.getInvoiceUnit());
        settlementInfoVo.setInvoiceDate(loanCar.getInvoiceDate());
        settlementInfoVo.setInvoicePrice(loanCar.getInvoicePrice());
        settlementInfoVo.setRegistOwner(loanCar.getRegistOwner());
        settlementInfoVo.setPlateNo(loanCar.getPlateNo());
        settlementInfoVo.setPlateType(loanCar.getPlateType());
        settlementInfoVo.setFirstRegistDate(loanCar.getFirstRegistDate());
        settlementInfoVo.setRegistDate(loanCar.getRegistDate());
        settlementInfoVo.setMortgageDate(loanCar.getMortgageDate());

        //还款计划获取
        RepaymentFormulaInterface repaymentFormulaInterface = new RepaymentFormulaInterface() {
        };
        RepaymentPlanParam repaymentPlanParam = new RepaymentPlanParam();
        repaymentPlanParam.setFinancingAmount(new BigDecimal(loanExt.getFinancingAmount()));
        repaymentPlanParam.setFirstStatementDate(loanDetail.getFirstRepayDate());
        repaymentPlanParam.setGracePeriod(cmBank.getGracePeriod());
        repaymentPlanParam.setTerm(Integer.parseInt(loanExt.getTerm().toString()));
        repaymentPlanParam.setMonthRepayInterest(loanDetail.getMonthRepayInterest());
        repaymentPlanParam.setMonthRepayPrincipal(loanDetail.getMonthRepayPrincipal());
        repaymentPlanParam.setFirstRepayInterest(loanDetail.getFirstRepayInterest());
        repaymentPlanParam.setFirstRepayPrincipal(loanDetail.getFirstRepayPrincipal());
        repaymentPlanParam.setLastRepayInterest(loanDetail.getLastRepayInterest());
        repaymentPlanParam.setLastRepayPrincipal(loanDetail.getLastRepayPrincipal());
        settlementInfoVo
            .setRepaymentPlans(repaymentFormulaInterface.getRepaymentPlans(repaymentPlanParam));

        //表单信息
        settlementInfoVo.setSettlementInfoStatus(loanStatus.getSettlementInfoStatus());
        settlementInfoVo.setSettlementDate(loanExt.getSettlementDate());
        settlementInfoVo.setSettlementRemark(loanExt.getSettlementRemark());
        return settlementInfoVo;
    }

    public AjaxResult input(SettlementInfoBo settlementInfoBo) {
        long loanId = Long.parseLong(settlementInfoBo.getLoanId());
        Optional<LoanStatus> optionalLoanStatus = loanStatusMapper.selectByLoanId(loanId);
        LoanStatus loanStatus = optionalLoanStatus
            .orElseThrow(() -> new LoanParameterException("业务状态数据异常请联系管理员"));

        Long settlementInfoStatus = loanStatus.getSettlementInfoStatus();
        if (SettlementInfoStatus.INIT.status != settlementInfoStatus) {
            return AjaxResult.error("当前状态不可提交");
        }

        loanStatus.setSettlementInfoStatus(settlementInfoBo.getOperatorStatus());
        loanStatus.setSettlementInfoId(SecurityUtils.getLoginUserId());
        loanStatus.setSettlementInfoTime(LocalDateTime.now());
        loanStatusMapper.updateById(loanStatus);

        Optional<Loan> optionalLoan
            = Optional.ofNullable(loanMapper.selectById(loanId));
        Loan loan = optionalLoan.orElseThrow(() -> new LoanParameterException("无该业务数据"));

        if (SettlementInfoStatus.SUBMIT.status == settlementInfoBo.getOperatorStatus()) {
            loan.setBusinessStatus(LoanStatusEnum.SETTLE.status);
            loanMapper.updateById(loan);
        }

        Optional<LoanExt> optionalLoanExt = loanExtMapper.selectByLoanId(loanId);
        LoanExt loanExt = optionalLoanExt
            .orElseThrow(() -> new LoanParameterException("业务数据扩展信息异常"));
        loanExt.setSettlementDate(settlementInfoBo.getSettlementDate());
        loanExt.setSettlementRemark(settlementInfoBo.getSettlementRemark());
        loanExtMapper.updateById(loanExt);
        return AjaxResult.success();
    }

}
